#include "server_socket.h"
#include "ui_tcp_mainwindow.h"
#include <QPushButton>

TCP_MainWindow::TCP_MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::TCP_MainWindow)
{
    ui->setupUi(this);

    setWindowTitle("TCP Test Tool 1.2");
    setFixedSize(660, 510);

    server_socket = NULL;
    //cliet_socket = NULL;
    cliet = NULL;

    server_socket = new QTcpServer(this);       //内存自动回收
    cliet = new QTcpSocket(this);
    //server_socket->listen(QHostAddress::Any, 12345);

    //关联客户端连接信号newConnection
    connect(server_socket, &QTcpServer::newConnection, this, &TCP_MainWindow::new_client); //连接客户端
//    connect(server_socket, &QTcpServer::newConnection,
//            [=] ()
//            {
//                cliet_socket = server_socket->nextPendingConnection();
//                //获取客户端的IP和端口
//                QString ip = cliet_socket->peerAddress().toString();
//                quint16 port = cliet_socket->peerPort();

//                QString tmp = QString("{%1: %2}:成功连接").arg(ip).arg(port);
//                //QString client_num =
//                ui->textEdit_client_num->setText(QString("%1:%2").arg(ip).arg(port));
//                ui->textEdit_serv_receive->setText(tmp);

//                //读取客户端发送的消息，调用readyRead信号
//                connect(cliet_socket, &QTcpSocket::readyRead,
//                        [=] ()
//                        {
//                            QByteArray array = cliet_socket->readAll();
//                            //ui->textEdit_read->setText(array);
//                            ui->textEdit_serv_receive->append(array);
//                        }
//                        );
//            }
//           );


    //客户端信号
    connect(cliet, &QTcpSocket::connected,
            [=]()
            {
                ui->textEdit_clie_receive->append("成功连接到服务");
            }
            );

    connect(cliet, &QTcpSocket::readyRead,
            [=]()
            {
                //获取对方发送的内容
                QByteArray array = cliet->readAll();
                //追加到编辑区中
                ui->textEdit_clie_receive->append(array);
            }

            );

    connect(cliet, &QTcpSocket::disconnected,
            [=]()
            {
                ui->textEdit_clie_receive->append("已断开服务器连接");
            }

            );

}

TCP_MainWindow::~TCP_MainWindow()
{
    delete ui;
}

//服务器端定义的槽函数
void TCP_MainWindow::on_pushButton_bind_clicked()
{
    quint16 serv_port = ui->lineEdit_serv_port->text().toUInt();    //获取lineEdit文本内容
    quint32 serv_ip = ui->lineEdit_serv_ip->text().toUInt();
    if (!serv_ip)
    {
        server_socket->listen(QHostAddress::Any, serv_port);
    }
    else
    {
        server_socket->listen(QHostAddress(serv_ip), serv_port);
    }
}

void TCP_MainWindow::new_client()
{
    qDebug() << "new client";

    TcpInfo tcpInfo;        //自定义的结构体
    QTcpSocket *cliet_socket = server_socket->nextPendingConnection();
    tcpInfo.cliet_socket = cliet_socket;  //给结构体成员函数赋值
    vTcpInfo.append(tcpInfo);   //往vector数组中插入（结构体类型）数据

    //获取客户端的IP和端口
    QString ip = cliet_socket->peerAddress().toString();
    quint16 port = cliet_socket->peerPort();
    QString tmp = QString("{%1: %2}:成功连接").arg(ip).arg(port);
    //显示连接的客户端IP和端口，并在文本编辑区显示成功连接
    ui->textEdit_client_num->append(QString("%1:%2").arg(ip).arg(port));
    ui->textEdit_serv_receive->setText(tmp);


    //读取客户端发送的消息，调用readyRead信号
    connect(cliet_socket, &QTcpSocket::readyRead, this, &TCP_MainWindow::read_client_data);
    //检测掉线信号
    connect(cliet_socket, &QTcpSocket::disconnected, this, &TCP_MainWindow::client_dis);

    /* socket出错 -> 出错处理 */
    connect(cliet_socket, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(show_error(QAbstractSocket::SocketError)));
}

void TCP_MainWindow::read_client_data()
{
    qDebug() << "read client data";
    //可以实现同时读取多个客户端发送过来的消息
    QTcpSocket *receive = (QTcpSocket*)sender();        //sender函数只在调用的槽函数中有效

    //有内容可读     bytesAvailable 返回传入带读取的字节
    if(receive->bytesAvailable() > 0)
    {
        //获取客户端的IP和端口
        QString ip = receive->peerAddress().toString();
        quint16 port = receive->peerPort();
        QString tmp = QString("{%1: %2}").arg(ip).arg(port);
        QByteArray array = receive->readAll();
        QString data = tmp + array;             //将对方IP地址和端口以及发送消息打印
        ui->textEdit_serv_receive->append(data);
        //ui->textEdit_serv_receive->
    }
}

void TCP_MainWindow::on_pushButton_serv_send_clicked()
{
//    if(NULL == cliet_socket)
//    {
//        return;
//    }
//    QString str = ui->textEdit_serv_send->toPlainText();
//    cliet_socket->write(str.toUtf8().data());
}

void TCP_MainWindow::client_dis()
{
    QTcpSocket *obj = (QTcpSocket*)sender();//掉线对象
    obj->close();
    cleanConnect(obj);                      //自定义函数
    qDebug()<<obj->peerAddress().toString();//打印出掉线对象的ip
}

void TCP_MainWindow::on_pushButton_serv_clear_clicked()
{
    ui->textEdit_serv_receive->clear();
}

void TCP_MainWindow::on_pushButton_serv_disconn_clicked()
{
    //服务器端不允许主动断开客户端，除非关闭服务器
    ui->pushButton_serv_disconn->setEnabled(false);
}

void TCP_MainWindow::cleanConnect(QTcpSocket *socket)
{
    TcpInfo tcpInfo;
    int i = 0;
    QVector<TcpInfo>::iterator iter;

    for (iter = vTcpInfo.begin(); iter != vTcpInfo.end(); iter++)
    {
        //从当前连接的所有socket中，函数传入的socket
        if(iter->cliet_socket == socket)
        {
            iter->index = i;
            tcpInfo = *iter;
            vTcpInfo.remove(tcpInfo.index);
        }
        i++;
    }
}

void TCP_MainWindow::show_error(QAbstractSocket::SocketError)
{
    QTcpSocket *obj = (QTcpSocket*)sender();
    qDebug() << obj->errorString();
    obj->close(); // 关cocket
}


//客户端定义的槽函数
void TCP_MainWindow::on_pushButton_connect_clicked()
{
    //获取服务器ip和端口
    QString ip = ui->lineEdit_clie_ip->text();
    qint16 port = ui->lineEdit_clie_port->text().toInt();

    //主动和服务器建立连接
    cliet->connectToHost(QHostAddress(ip), port);

    //客户端主动连接服务器，按下Connect按钮之后，成功连接，并且按钮显示已连接（Disconnect）
    ui->pushButton_connect->setText("Disconnect");
}

void TCP_MainWindow::on_pushButton_clie_send_clicked()
{
    if(NULL == cliet)
    {
        return;
    }
    QString str = ui->textEdit_clie_send->toPlainText();
    cliet->write(str.toUtf8().data());
}

void TCP_MainWindow::on_pushButton_clie_clear_clicked()
{
    ui->textEdit_clie_receive->clear();
}

void TCP_MainWindow::on_pushButton_clie_disconn_clicked()
{
//    if(NULL == cliet)
//    {
//        return;
//    }
    cliet->disconnectFromHost();
    cliet->close();
    //cliet = NULL;     //千万不能置空，否则导致按钮再次按下时，无法再找到client所指向的地址。（找不到父亲了）

    //客户端主动按下Disconnect按钮之后，Connect按钮恢复原状
    ui->pushButton_connect->setText("Connect");
}
